import {getConfig} from "../core";
import {InvalidParamsError} from "../core/errors";
import {hintError} from "./toast";
import dynamicImport from "../core/require";

/**
 * Map
 * @param {{
 *     el:HTMLElement|string,
 *     mapType?:boolean,
 *     overView?:boolean,
 *     toolBar?:Object,
 *     autoComplete?:HTMLElement|string,
 *     mapStyle?:string,
 *     zoom?:number,
 *     viewMode?:string,
 *     pitch?:number,
 *     expandZoomRange?:boolean,
 * }} options
 * @return {Promise<unknown>}
 */
export default function(options = {}) {
	return new Promise(async function(resolve, reject) {
		try {
			await dynamicImport(
				resolveUrl(options)
			);

			resolve(initMap(options));
		} catch (e) {
			hintError("加载地图组件失败，轻稍后刷新重试~");
			reject(e);
		}
	});
};

// 完成一个 key
function resolveKey(options) {
	if (options.key) {
		return options.key;
	}

	const config = getConfig('map');
	if (!config.key) {
		throw new InvalidParamsError('map.key not config!');
	}

	return config.key;
}

// 生成加载的地图地址
function resolveUrl(options) {
	return `https://webapi.amap.com/maps?v=1.4.15&key=${resolveKey(options)}`;
}

// 初始化options
function initOptions(options) {
	if (typeof options.center === 'string') {
		options.center = options.center.split(',', 2).map(parseFloat);
	}

	return Object.assign({
		mapType: false,
		overView: false,

		toolBar: {
			liteStyle: true
		},

		autoComplete: '',
		mapStyle: 'amap://styles/' + (options.style || "normal"),
		zoom: 14,

		// viewMode: '3D',
		// pitch: 0
		// expandZoomRange: true,
	}, options);
}

// 初始化中心点
function updatePositionFactory(container, map, options) {
	const HTML = `<input type="hidden" name="${options.name || ''}" />`;
	const positionInput = $(HTML).appendTo(container);
	const handler = function(lng, lat) {
		positionInput.val(lng + ',' + lat);
	};

	const center = options.center;
	if (center) {
		map.setCenter([center[0], center[1]]);
		handler(center[0], center[1]);
	}

	return handler;
}

// 初始化其他组件
async function initPlugins(map, options, updatePosition) {
	// 输入自动提示
	const autoCompleteInput = $(options.autoComplete);

	// 地图显示的位置点
	let positionPicker = null;

	// 点标记
	await dynamicImport('https://webapi.amap.com/ui/1.0/main.js');
	AMapUI.loadUI(['misc/PositionPicker'], function(PositionPicker) {
		//设定为拖拽地图模式，可选'dragMap'、'dragMarker'，默认为'dragMap'
		positionPicker = new PositionPicker({
			mode: options.mode || 'dragMap',
			map: map
		});
		positionPicker.start(options.center);

		let isFirst = !!options.center;
		positionPicker.on('success', function(res) {
			if (isFirst) {
				isFirst = false;
				return;
			}

			if (autoCompleteInput) {
				autoCompleteInput.val(res.address);
			}

			updatePosition(res.position.lng, res.position.lat);
		});
	});

	map.addControl(new AMap.ToolBar(options.toolBar)); //工具条
	map.addControl(new AMap.Scale()); //比例尺
	options.overView && map.addControl(new AMap.OverView({isOpen: true})); //鹰眼
	options.mapType && map.addControl(new AMap.MapType()); //类别切换

	//输入提示
	if (autoCompleteInput[0] instanceof HTMLElement) {
		const autocomplete = new AMap.Autocomplete({
			input: autoCompleteInput[0]
		});

		AMap.event.addListener(autocomplete, "select", function(res) {
			if (!res.poi.location) return;

			autoCompleteInput.val(res.poi.name);

			const position = [
				res.poi.location.lng,
				res.poi.location.lat
			];

			map.setCenter(position);

			if (positionPicker) {
				positionPicker.marker.setPosition(position);
			}

			updatePosition(position[0], position[1]);
		});
	}

	//覆盖物
	options.markers && options.markers.forEach(function(item) {
		new AMap.Marker(item).setMap(map);
	});

	//圆
	options.circles && options.circles.forEach(function(item) {
		new AMap.Circle(item).setMap(map);
	});

	map.setFitView();


}

// 初始化地图
async function initMap(options) {
	options = initOptions(options);

	const container = $(options.el);
	const map = new AMap.Map(container[0], options);

	// 隐藏logo和版权
	container.children(".amap-logo").remove();
	container.children(".amap-copyright").remove();

	// 初始化中心点
	const updatePosition = updatePositionFactory(container, map, options);

	// 初始化其他插件
	const plugins = ['AMap.ToolBar', 'AMap.Scale'];
	options.overView && plugins.push('AMap.OverView');
	options.mapType && plugins.push('AMap.MapType');
	options.autoComplete && plugins.push('AMap.Autocomplete');
	AMap.plugin(plugins, function() {
		initPlugins(map, options, updatePosition);
	});

	return map;
}
